package com.record.utils;

import net.sf.jmimemagic.Magic;
import net.sf.jmimemagic.MagicMatch;
import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
import org.apache.poi.hpsf.GUID;

import java.io.*;
import java.net.*;
import java.util.*;
import java.util.Map.Entry;

public class HttpHelper {
    private int responsecode = 0;
    private static final Log log = LogFactory.getLog(HttpHelper.class);
    private Map<String, String> cookies = new HashMap<String, String>();

    public Map<String, String> getCookies() {
        return cookies;
    }

    public void setCookies(Map<String, String> cookies) {
        this.cookies = cookies;
    }

    public String DoHttpGetRequest(String surl, Map<String, String> headers, String encoding) throws Exception {
        String ret = "";
        String proxyip = "";
        String proxyport = "";
        ResourceBundle propreader = null;
        try {
            propreader = ResourceBundle.getBundle("proxy");
            if (propreader != null) {
                proxyip = propreader.getString("proxyip");
                proxyport = propreader.getString("proxyport");
            }
        } catch (Exception e) {

        }

        HttpURLConnection con = null;
        URL url = new URL(surl);
        if (proxyip != null && !proxyip.equals("")) {
            log.debug("set system proxy,proxy ip " + proxyip + ",proxyport " + proxyport);
            SocketAddress sa = new InetSocketAddress(proxyip, Integer.parseInt(proxyport));
            Proxy proxy = new Proxy(Proxy.Type.HTTP, sa);
            con = (HttpURLConnection) url.openConnection(proxy);
        } else {
            con = (HttpURLConnection) url.openConnection();
        }
        con.setRequestMethod("GET");
        con.setConnectTimeout(600000);
        con.setReadTimeout(600000);
        Iterator<Entry<String, String>> it = headers.entrySet().iterator();
        while (it.hasNext()) {
            Entry<String, String> entry = it.next();
            log.debug("add http header key:" + entry.getKey() + ",value:" + entry.getValue());
            con.setRequestProperty(entry.getKey(), entry.getValue());
        }
        responsecode = con.getResponseCode();
        String key = "";
        Map<String, List<String>> fields = con.getHeaderFields();
        Iterator<Entry<String, List<String>>> testit = fields.entrySet().iterator();
        while (testit.hasNext()) {
            Entry<String, List<String>> entry = testit.next();
            String mykey = entry.getKey();
            log.debug("Header key:" + mykey);
            List<String> values = entry.getValue();
            for (int i = 0; i < values.size(); i++) {
                String value = values.get(i);
                log.debug("value:" + value);
            }
        }

        List<String> returncookies = fields.get("Set-Cookie");
        if (returncookies != null) {
            Iterator<String> it2 = returncookies.iterator();
            while (it2.hasNext()) {
                String cookieVal = it2.next();
                int nPos = cookieVal.indexOf(";");
                if (nPos > 0) {
                    cookieVal = cookieVal.substring(0, nPos);
                }
                String[] pair = cookieVal.split("=");
                if (pair.length == 2) {
                    log.debug("add cookie key:" + pair[0] + ",value:" + pair[1]);
                    cookies.put(pair[0], pair[1]);
                }
            }
        }
        BufferedReader reader = null;
        try {
            reader = new BufferedReader(new InputStreamReader(con.getInputStream(), encoding));
            StringBuffer sbuf = new StringBuffer();
            String s;
            while ((s = reader.readLine()) != null) {
                sbuf.append(s);
            }
            ret = sbuf.toString();
            log.debug("get response:" + ret);
        } catch (Exception e) {
            throw e;
        } finally {
            if (reader != null) {
                try {
                    reader.close();
                    con.disconnect();
                } catch (IOException e) {
                }
            }
        }
        return ret;
    }


    public boolean DoHttpGetFileRequest(String surl, Map<String, String> headers, String encoding, String outputfilename, String proxyip, String proxyport) throws Exception {
        boolean ret = false;

        HttpURLConnection con = null;
        URL url = new URL(surl);
        if (proxyip != null && !proxyip.equals("")) {
            log.debug("set system proxy,proxy ip " + proxyip + ",proxyport " + proxyport);
            SocketAddress sa = new InetSocketAddress(proxyip, Integer.parseInt(proxyport));
            Proxy proxy = new Proxy(Proxy.Type.HTTP, sa);
            con = (HttpURLConnection) url.openConnection(proxy);
        } else {
            con = (HttpURLConnection) url.openConnection();
        }
        con.setRequestMethod("GET");
        con.setConnectTimeout(600000);
        con.setReadTimeout(600000);
        Iterator<Entry<String, String>> it = headers.entrySet().iterator();
        while (it.hasNext()) {
            Entry<String, String> entry = it.next();
            log.debug("add http header key:" + entry.getKey() + ",value:" + entry.getValue());
            con.setRequestProperty(entry.getKey(), entry.getValue());
        }
        responsecode = con.getResponseCode();
        String key = "";
        Map<String, List<String>> fields = con.getHeaderFields();
        List<String> returncookies = fields.get("Set-Cookie");
        if (returncookies != null) {
            Iterator<String> it2 = returncookies.iterator();
            while (it2.hasNext()) {
                String cookieVal = it2.next();
                int nPos = cookieVal.indexOf(";");
                if (nPos > 0) {
                    cookieVal = cookieVal.substring(0, nPos);
                }
                String[] pair = cookieVal.split("=");
                if (pair.length == 2) {
                    log.debug("add cookie key:" + pair[0] + ",value:" + pair[1]);
                    cookies.put(pair[0], pair[1]);
                }
            }
        }
        InputStream is = null;
        OutputStream os = null;
        try {
            is = con.getInputStream();
            os = new BufferedOutputStream(new FileOutputStream(new File(outputfilename)));
            byte[] buf = new byte[4096];
            int recv = 0;
            int len = 0;
            do {
                len = is.read(buf, 0, 4096);
                recv += len;
                if (len > 0) {
                    os.write(buf, 0, len);
                }
            } while (len > 0);
            ret = true;
        } catch (Exception e) {
            throw e;
        } finally {
            if (is != null) {
                try {
                    is.close();
                    con.disconnect();
                } catch (IOException e) {
                }
            }
            if (os != null) {
                try {
                    os.close();
                } catch (Exception e) {

                }
            }
        }
        return ret;
    }


    public boolean DoHttpPostRequestToStream(String surl, Map<String, String> headers, String encoding, String data, OutputStream deststream, String proxyip, String proxyport) throws Exception {
        return DoHttpGenericRequestToStream("POST", surl, headers, encoding, data, deststream, proxyip, proxyport);
    }


    public boolean DoHttpGetRequestToStream(String surl, Map<String, String> headers, String encoding, String data, OutputStream deststream, String proxyip, String proxyport) throws Exception {
        return DoHttpGenericRequestToStream("GET", surl, headers, encoding, data, deststream, proxyip, proxyport);
    }

    public boolean DoHttpGenericRequestToStream(String method, String surl, Map<String, String> headers, String encoding, String data, OutputStream deststream, String proxyip, String proxyport) throws Exception {
        boolean ret = false;

        HttpURLConnection con = null;
        URL url = new URL(surl);
        if (proxyip != null && !proxyip.equals("")) {
            log.debug("set system proxy,proxy ip " + proxyip + ",proxyport " + proxyport);
            SocketAddress sa = new InetSocketAddress(proxyip, Integer.parseInt(proxyport));
            Proxy proxy = new Proxy(Proxy.Type.HTTP, sa);
            con = (HttpURLConnection) url.openConnection(proxy);
        } else {
            con = (HttpURLConnection) url.openConnection();
        }
        con.setRequestMethod(method);
        con.setConnectTimeout(600000);
        con.setReadTimeout(600000);
        Iterator<Entry<String, String>> it = headers.entrySet().iterator();
        while (it.hasNext()) {
            Entry<String, String> entry = it.next();
            log.debug("add http header key:" + entry.getKey() + ",value:" + entry.getValue());
            con.setRequestProperty(entry.getKey(), entry.getValue());
        }
        con.setDoOutput(true);
        con.setDoInput(true);
        OutputStream os = null;
        if (data != null && data.length() > 0) {

            try {
                os = con.getOutputStream();
                os.write(data.getBytes());
                os.flush();
            } catch (Exception e) {
                throw e;
            } finally {
                if (os != null) {
                    try {
                        os.close();
                        con.disconnect();
                    } catch (IOException e) {
                    }
                }
            }
        }
        responsecode = con.getResponseCode();
        String key = "";
        Map<String, List<String>> fields = con.getHeaderFields();
        List<String> returncookies = fields.get("Set-Cookie");
        if (returncookies != null) {
            Iterator<String> it2 = returncookies.iterator();
            while (it2.hasNext()) {
                String cookieVal = it2.next();
                int nPos = cookieVal.indexOf(";");
                if (nPos > 0) {
                    cookieVal = cookieVal.substring(0, nPos);
                }
                String[] pair = cookieVal.split("=");
                if (pair.length == 2) {
                    log.debug("add cookie key:" + pair[0] + ",value:" + pair[1]);
                    cookies.put(pair[0], pair[1]);
                }
            }
        }
        InputStream is = null;
        os = null;
        try {
            is = con.getInputStream();
            os = deststream;
            byte[] buf = new byte[4096];
            int recv = 0;
            int len = 0;
            do {
                len = is.read(buf, 0, 4096);
                recv += len;
                if (len > 0) {
                    os.write(buf, 0, len);
                }
            } while (len > 0);
            ret = true;
        } catch (Exception e) {
            throw e;
        } finally {
            if (is != null) {
                try {
                    is.close();
                    con.disconnect();
                } catch (IOException e) {
                }
            }
        }
        return ret;
    }

    public String DoHttpGenericRequest(String method, String surl, Map<String, String> headers, String data, String encoding, String proxyip, String proxyport) throws Exception {

        String ret = "";

        HttpURLConnection con = null;
        URL url = new URL(surl);
        if (proxyip != null && !proxyip.equals("")) {
            log.debug("set system proxy,proxy ip " + proxyip + ",proxyport " + proxyport);
            SocketAddress sa = new InetSocketAddress(proxyip, Integer.parseInt(proxyport));
            Proxy proxy = new Proxy(Proxy.Type.HTTP, sa);
            con = (HttpURLConnection) url.openConnection(proxy);
        } else {
            con = (HttpURLConnection) url.openConnection();
        }
        con.setRequestMethod(method);
        con.setConnectTimeout(600000);
        con.setReadTimeout(600000);
        con.setDoOutput(true);
        con.setDoInput(true);

        Iterator<Entry<String, String>> it = headers.entrySet().iterator();
        while (it.hasNext()) {
            Entry<String, String> entry = it.next();
            log.debug("add http header key:" + entry.getKey() + ",value:" + entry.getValue());
            con.setRequestProperty(entry.getKey(), entry.getValue());
        }

        if (data != null && data.length() > 0) {
            OutputStream os = null;
            try {
                os = con.getOutputStream();
                os.write(data.getBytes(encoding));
                os.flush();
            } catch (Exception e) {
                throw e;
            } finally {
                if (os != null) {
                    try {
                        os.close();
                        con.disconnect();
                    } catch (IOException e) {
                    }
                }
            }
        }
        responsecode = con.getResponseCode();
        Map<String, List<String>> fields = con.getHeaderFields();
        List<String> returncookies = fields.get("Set-Cookie");
        if (returncookies != null) {
            Iterator<String> it2 = returncookies.iterator();
            while (it2.hasNext()) {
                String cookieVal = it2.next();
                int nPos = cookieVal.indexOf(";");
                if (nPos > 0) {
                    cookieVal = cookieVal.substring(0, nPos);
                }
                String[] pair = cookieVal.split("=");
                if (pair.length == 2) {
                    log.debug("add cookie key:" + pair[0] + ",value:" + pair[1]);
                    cookies.put(pair[0], pair[1]);
                }
            }
        }
        BufferedReader reader = null;
        try {
            reader = new BufferedReader(new InputStreamReader(con.getInputStream(), encoding));
            StringBuffer sbuf = new StringBuffer();
            String s;
            while ((s = reader.readLine()) != null) {
                sbuf.append(s);
            }
            ret = sbuf.toString();
            log.debug("get response:" + ret);
        } catch (Exception e) {
            throw e;
        } finally {
            if (reader != null) {
                try {
                    reader.close();
                    con.disconnect();
                } catch (IOException e) {
                }
            }
        }
        return ret;
    }


    public String DoHttpPostRequest(String surl, Map<String, String> headers, String data, String encoding, String proxyip, String proxyport) throws Exception {

        String ret = "";

        HttpURLConnection con = null;
        URL url = new URL(surl);
        if (proxyip != null && !proxyip.equals("")) {
            log.debug("set system proxy,proxy ip " + proxyip + ",proxyport " + proxyport);
            SocketAddress sa = new InetSocketAddress(proxyip, Integer.parseInt(proxyport));
            Proxy proxy = new Proxy(Proxy.Type.HTTP, sa);
            con = (HttpURLConnection) url.openConnection(proxy);
        } else {
            con = (HttpURLConnection) url.openConnection();
        }
        con.setRequestMethod("POST");
        con.setConnectTimeout(600000);
        con.setReadTimeout(600000);

        Iterator<Entry<String, String>> it = headers.entrySet().iterator();
        while (it.hasNext()) {
            Entry<String, String> entry = it.next();
            log.debug("add http header key:" + entry.getKey() + ",value:" + entry.getValue());
            con.setRequestProperty(entry.getKey(), entry.getValue());
        }
        con.setDoOutput(true);
        con.setDoInput(true);

        OutputStream os = null;
        try {
            os = con.getOutputStream();
            os.write(data.getBytes());
            os.flush();
        } catch (Exception e) {
            throw e;
        } finally {
            if (os != null) {
                try {
                    os.close();
                    con.disconnect();
                } catch (IOException e) {
                }
            }
        }
        responsecode = con.getResponseCode();
        Map<String, List<String>> fields = con.getHeaderFields();
        List<String> returncookies = fields.get("Set-Cookie");
        if (returncookies != null) {
            Iterator<String> it2 = returncookies.iterator();
            while (it2.hasNext()) {
                String cookieVal = it2.next();
                int nPos = cookieVal.indexOf(";");
                if (nPos > 0) {
                    cookieVal = cookieVal.substring(0, nPos);
                }
                String[] pair = cookieVal.split("=");
                if (pair.length == 2) {
                    log.debug("add cookie key:" + pair[0] + ",value:" + pair[1]);
                    cookies.put(pair[0], pair[1]);
                }
            }
        }
        BufferedReader reader = null;
        try {
            reader = new BufferedReader(new InputStreamReader(con.getInputStream(), encoding));
            StringBuffer sbuf = new StringBuffer();
            String s;
            while ((s = reader.readLine()) != null) {
                sbuf.append(s);
            }
            ret = sbuf.toString();
            log.debug("get response:" + ret);
        } catch (Exception e) {
            throw e;
        } finally {
            if (reader != null) {
                try {
                    reader.close();
                    con.disconnect();
                } catch (IOException e) {
                }
            }
        }
        return ret;
    }

    public int getResponsecode() {
        return responsecode;
    }

    public void setResponsecode(int responsecode) {
        this.responsecode = responsecode;
    }

    //对于NGS上传，只能支持上传一个文件
    //文件路径 eliteUploadPath
    //客户端token
    //eliteUploadFile
    public String uploadFile(String surl, Map<String, String> parameters, Map<String, String> files, Map<String, String> headers, String proxyip, String proxyport) {
        String ret = "";
        log.debug("begin upload file to " + surl);
        HttpURLConnection conn = null;

        try {
            GUID guid = new GUID();

            String BOUNDARY = "---------------------------" + guid.toString(); //boundary就是request头和上传文件内容的分隔符


            URL url = new URL(surl);
            if (proxyip != null && !proxyip.equals("")) {
                log.debug("set system proxy,proxy ip " + proxyip + ",proxyport " + proxyport);
                SocketAddress sa = new InetSocketAddress(proxyip, Integer.parseInt(proxyport));
                Proxy proxy = new Proxy(Proxy.Type.HTTP, sa);
                conn = (HttpURLConnection) url.openConnection(proxy);
            } else {
                conn = (HttpURLConnection) url.openConnection();
            }
            conn.setConnectTimeout(5000);
            conn.setReadTimeout(30000);
            conn.setDoOutput(true);
            conn.setDoInput(true);
            conn.setUseCaches(false);
            conn.setRequestMethod("POST");
            Iterator<Entry<String, String>> it = headers.entrySet().iterator();
            while (it.hasNext()) {
                Entry<String, String> entry = it.next();
                conn.setRequestProperty(entry.getKey(), entry.getValue());
            }

            conn.setRequestProperty("Content-Type", "multipart/form-data; boundary=" + BOUNDARY);

            OutputStream out = new DataOutputStream(conn.getOutputStream());
            // text
            if (parameters != null) {
                StringBuffer strBuf = new StringBuffer();
                Iterator<Entry<String, String>> iter = parameters.entrySet().iterator();
                while (iter.hasNext()) {
                    Entry<String, String> entry = iter.next();
                    String inputName = (String) entry.getKey();
                    String inputValue = (String) entry.getValue();
                    if (inputValue == null) {
                        continue;
                    }
                    strBuf.append("\r\n").append("--").append(BOUNDARY).append("\r\n");
                    strBuf.append("Content-Disposition: form-data; name=\"" + inputName + "\"\r\n\r\n");
                    strBuf.append(inputValue);
                }
                out.write(strBuf.toString().getBytes());
            }

            // file
            if (files != null) {
                Iterator<Entry<String, String>> iter = files.entrySet().iterator();
                while (iter.hasNext()) {
                    Entry<String, String> entry = iter.next();
                    String inputName = (String) entry.getKey();
                    String inputValue = (String) entry.getValue();

                    if (inputValue == null) {
                        log.error("fieldname " + inputName + " has no filename given");
                        continue;
                    }
                    File file = new File(inputValue);
                    if (!file.exists()) {
                        log.error("file " + inputValue + " is not exist");
                    }
                    String filename = file.getName();
                    log.debug("");
                    MagicMatch match = Magic.getMagicMatch(file, false, true);
                    String contentType = match.getMimeType();

                    StringBuffer strBuf = new StringBuffer();
                    strBuf.append("\r\n").append("--").append(BOUNDARY).append("\r\n");
                    strBuf.append("Content-Disposition: form-data; name=\"" + inputName + "\"; filename=\"" + filename + "\"\r\n");
                    strBuf.append("Content-Type:" + contentType + "\r\n\r\n");

                    out.write(strBuf.toString().getBytes());

                    DataInputStream in = new DataInputStream(new FileInputStream(file));
                    int bytes = 0;
                    byte[] bufferOut = new byte[1024];
                    while ((bytes = in.read(bufferOut)) != -1) {
                        out.write(bufferOut, 0, bytes);
                    }
                    in.close();
                }
            }

            byte[] endData = ("\r\n--" + BOUNDARY + "--\r\n").getBytes();
            out.write(endData);
            out.flush();
            out.close();
            responsecode = conn.getResponseCode();
            // 读取返回数据    
            StringBuffer strBuf = new StringBuffer();
            BufferedReader reader = new BufferedReader(new InputStreamReader(conn.getInputStream()));
            String line = null;
            while ((line = reader.readLine()) != null) {
                strBuf.append(line).append("\n");
            }
            ret = strBuf.toString();
            reader.close();
            reader = null;
        } catch (Exception e) {
            log.error("发送POST请求出错。" + surl, e);
        } finally {
            if (conn != null) {
                conn.disconnect();
                conn = null;
            }
        }
        return ret;
    }

    public static void main(String[] args) {
        HttpHelper helper = new HttpHelper();
        String sURL = "http://192.168.192.187:8080/RBRecordGateway/";
        HashMap<String, String> headers = new HashMap<String, String>();
        headers.put("Content-Type", "application/x-www-form-urlencoded");
        try {
            String response = helper.DoHttpGetRequest(sURL, headers, "UTF-8");
            System.out.println(response);
        } catch (Exception e) {
            // TODO Auto-generated catch block
            e.printStackTrace();
        }
    }
}
